package MultiThread;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class CompleteTest {

    private  static Logger log = Logger.getLogger("测试");

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(
                ()->{
                    try {
                        TimeUnit.SECONDS.sleep(3);
                        log.info(Thread.currentThread().toString()+": 1");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "hello";})
                .thenApplyAsync(one->{
                            log.info(Thread.currentThread().toString()+": 2");
                    return one+" world";}
                    )
                .thenApplyAsync(two ->{
                    log.info(Thread.currentThread().toString()+": 3");
                    return two + " o(￣▽￣)ｄ";});
//        testList();
        log.info(Thread.currentThread().toString()+": 开始");

        log.info(Thread.currentThread().getName()+": " + completableFuture.get());

    }

    private static void testList() {
        List<CompletableFuture<List<Integer>>> completableFutureList = new ArrayList<>(4);
        for (int i = 0; i <= 30; i+=10) {
            CompletableFuture<List<Integer>> list = getIntegerList(i,10);
            completableFutureList.add(list);
        }

        List<Integer> join = completableFutureList.stream()
                .reduce((fn1, fn2) -> fn1.thenCombine(fn2, (integers, integers2) -> Stream.of(integers, integers2).flatMap(Collection::stream).collect(Collectors.toList())))
                .orElse(CompletableFuture.completedFuture(Collections.emptyList()))
                .join();
        System.out.println(join);
    }

    private static CompletableFuture<List<Integer>> getIntegerList(int startIndex, int size) {
        return CompletableFuture.supplyAsync(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return Stream.iterate(startIndex, item -> item + 1).limit(size).collect(Collectors.toList());
                }
        );
    }
}
